package com.mark.basic.service.Impl;

import com.mark.basic.annotation.PreAuthorize;
import com.mark.basic.service.IPermissionScanService;
import com.mark.basic.util.Classutil;
import com.mark.system.domain.Permission;
import com.mark.system.mapper.PermissionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
@Service
public class PermissionScanServiceImpl implements IPermissionScanService {
    @Autowired
    private PermissionMapper permissionMapper;
    // PREFIX -- 前缀
    private static final String  PKG_PREFIX   = "com.mark.";
    // SUFFIX -- 后缀
    private static final String  PKG_SUFFIX   = ".controller";
    @Override
    public void scan() {
        // 1、扫描自定义注解
          // 找到所有的controller
          // 找到所有的controller的方法
          // 遍历所有controller的方法，找到@PreAuthorize
        // 获取org.yaosang下面所有的模块目录
                String path = this.getClass().getResource("/").getPath() + "/com/mark/";
                File file = new File(path);
                // files 指的是mark下的所有包
                File[] files = file.listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File file) {
                        return file.isDirectory();
                    }
                });
                //获取org.yaosang.*.web.controller里面所有的类
                Set<Class> clazzes = new HashSet<>();
                for (File fileTmp : files) {
                    System.out.println(fileTmp.getName());
                    // PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX: com.mark.basic.controller
                    clazzes.addAll(Classutil.getClasses(PKG_PREFIX+fileTmp.getName()+PKG_SUFFIX));
                }
            //遍历所有的controller
                for (Class clazz : clazzes) {
                    // controller里面的所有方法
                    Method[] methods = clazz.getMethods();
                    if (methods==null || methods.length<1){
                        return;
                    }
                    for (Method method : methods) {
                        try {
                            // 拿到注解  .getAnnotation
                            PreAuthorize preAuthorizeAnno = method.getAnnotation(PreAuthorize.class);
                            if (preAuthorizeAnno==null)
                                continue;
                            String name = preAuthorizeAnno.name();
                            String permissionSn = preAuthorizeAnno.value(); // permissionSn == value
                            Permission permissionTmp = permissionMapper.loadBySn(permissionSn);
                           // 得到当前数据的uri
                            String uri = getUri(clazz, method);
                            //如果不存在就添加
                            if (permissionTmp == null) {
                                Permission permission = new Permission();
                                permission.setName(name);
                                permission.setSn(permissionSn);
                                permission.setUrl(uri);
                                permissionMapper.add(permission);
                            }else{
                                //如果不存在就修改
                                permissionTmp.setName(name);
                                permissionTmp.setSn(permissionSn);
                                permissionTmp.setUrl(uri);
                                permissionMapper.update(permissionTmp);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
    }

    /**
     * 获取uri
     * @param clazz
     * @param method
     * @return
     */
    private String getUri(Class clazz, Method method) {
        String classPath = "";
        Annotation annotation = clazz.getAnnotation(RequestMapping.class);
        if (annotation!=null){
            RequestMapping requestMapping = (RequestMapping) annotation;
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                classPath = values[0];
                if (!"".equals(classPath)&&!classPath.startsWith("/"))
                    classPath="/"+classPath;
            }
        }
        GetMapping getMapping =  method.getAnnotation(GetMapping.class);
        String methodPath = "";
        if (getMapping!=null){
            String[] values = getMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PostMapping postMapping =  method.getAnnotation(PostMapping.class);
        if (postMapping!=null){
            String[] values = postMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        DeleteMapping deleteMapping =  method.getAnnotation(DeleteMapping.class);
        if (deleteMapping!=null){
            String[] values = deleteMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        PutMapping putMapping =  method.getAnnotation(PutMapping.class);
        if (putMapping!=null){
            String[] values = putMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }

        }
        PatchMapping patchMapping = method.getAnnotation(PatchMapping.class);
        if (patchMapping!=null){
            String[] values = patchMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
        if (requestMapping!=null){
            String[] values = requestMapping.value();
            if(values!=null&&values.length>0){
                methodPath = values[0];
                if (!"".equals(methodPath)&&!methodPath.startsWith("/"))
                    methodPath="/"+methodPath;
            }
        }
        return classPath+methodPath;
    }

}